#ifndef LIST_IMAGE_H_INCLUDED
#define LIST_IMAGE_H_INCLUDED

/**
* @file list_image.h
*
*	 Nel file list_image.h viene definita la classe che gestisce la lista delle immagini
*	
* @author Favale Angelo
* @author Fagioli Alessio
*
* @version 1.0
*/

#include "../libreria.h"
/**
* La struttura node_image mantiene le informazioni relative ad una certa immagine sul Service
* Provider
*/
struct node_image
{
	char name[BUFFER_SIZE];		/**< Nome dell'immagine				*/
	struct node_image * next;	/**< Puntatore al prossimo elemento nella lista	*/
	pthread_mutex_t mutex;		/**< Semaforo per gestire la mutua esclusione
					*    delli informazioni relative agli accessi a
					*    quest'immagine				*/
	pthread_cond_t bloccoLettori;	/**< Condition per gestire la lettura
					*    dell'immagine				*/
	pthread_cond_t bloccoScrittori; /**< Condition per gestire la scrittura
					*    dell'immagine				*/
	int lettoriAttivi;		/**< Numero dei thread che stanno leggendo 
					*    l'immagine					*/
	bool scrittoreAttivo;		/**< Indica se c'è almeno un thread che sta
					*    scrivendo l'immagine			*/
	int lettoriBloccati;		/**< Numero dei thread che aspettano di poter
					*    leggere l'immagine				*/
	int scrittoriBloccati;		/**< Numero dei thread che aspettano di poter
					*    sovrascrivere l'immagine			*/
};

/**
* @class List_Image
*
*	 La classe List_Image implementa la gestione concorrente degli accessi alle immagini.
*/
class List_Image
{
	private:
		struct node_image * first; /**< puntatore a primo elemento della lista	*/
		pthread_mutex_t lock;	   /**< semaforo per gestire la mutua esclusione
					   *    sulla lista delle immagini		*/
		/**
		* @param nome_file Nome dell'immagine che si vuole cercare
		*
		* @return Puntatore alla struttura contenente le informazioni sugli accessi
		*	  di quell'immagine.\n
		*	  Nel caso in cui l'immagine cercata non sia presente ritorna come 
		*	  valore NULL
		*
		* Questo metodo viene usato all'interno di List_Image per trovare l'elemento
		* che mantiene le informazionin sugli accessi dell'immagine nome_file
		*/
		struct node_image * findNodo( char * nome_file );
	public:
		/**
		* Il costrutture si preoccupa di inizializzare la lista delle immagini, il
		* semaforo che ne gestisce la mutua esclusione e le condition per gestire
		* il problema dei lettori/scrittori.
		*/
		List_Image();

		/**
		* @param name_file Nome dell'immagine che si vuole registrare
		*
		* Questo metodo aggiunge alla lista delle immagini l'immagine chiamata 
		* name_file
		*/
		void add_image (char * name_file);

		/**
		* @param buffer Lista delle immagini presenti sul Service Provider ritornata
		*		per riferimento
		*
		* Questo metodo inserisce dentro buffer la lista delle immagini presenti sul
		* Service Provider.\n
		* La lista avrà il formato descritto nel seguente esempio:\n
		*	foto1.jpg;foto2.jpg;foto3.jpg#
		*/
		void get_list( char * buffer );

		/**
		* @param nome_file Nome dell'immagine di cui si vuole richiedere la scrittura
		*
		* Questo metodo permette di avere accesso in scrittura all'immagine 
		* nome_file.\n
		* La politica con cui si intendono gestire gli accessi è quella descritta dal
		* ben noto problema dei lettori/scrittori.\n
		* Esistono 2 possibili casi d'interesse in fase di scrittura:
		*   - immagine nome_file non presente sul Service Provider.\n
		*	  In questo caso l'immagine verrà aggiunta alla lista delle immagini 
		*	  gestite dal Service Provider.\n
		*	  Una volta usciti dalla funzione verrà data la possibilità al 
		*	  Service Provider di scrivere l'immagine richiesta.\n
		*   - immagine nome_file già presente sul Service Provider.\n
		* 	  In questo caso, una volta usciti dalla funzione, si consentirà al 
		*	  Service Provider di sovrascrivere l'immagine richiesta.
		*/
		void richiestaScrittura ( char * nome_file );

		/**
		* @param nome_file Nome dell'immagine di cui si vuole richiedere la lettura
		*
		* Questo metodo permette di avere accesso in lettura all'immagine nome_file.\n
		* La politica con cui si intendono gestire gli accessi è quella descritta dal
		* ben noto problema dei lettori/scrittori.\n
		* Una volta che questa funzione è terminata è possibile accedere in lettura
		* all'immagine nome_file
		*/
		void richiestaLettura ( char * nome_file );

		/**
		* @param nome_file Nome dell'immagine che si è finito di scrivere
		*
		* Questo metodo serve per comunicare la fine della scrittura dell'immagine 
		* nome_file.\n
		* La politica con cui si gestiscono gli accessi è quella descritta dal ben
		* noto problema dei lettori/scrittori.
		*/
		void rilascioScrittura ( char * nome_file );

		/**
		* @param nome_file Nome dell'immagine che si vuole smettere di leggere
		*
		* Questo metodo serve per comunicare la fine della lettura dell'immagine 
		* nome_file.\n
		* La politica con cui si gestiscono gli accessi è quella descritta dal ben
		* noto problema dei lettori/scrittori.
		*/
		void rilascioLettura (char * nome_file );
};
#endif
